///////////////////////////////////////////////////////////////////////////////
//
// DBT86 Project : Common Files : common.h
// Copyright (C) 2004 by Ben Hertzberg and Stanford University
// All Rights Reserved
//
// This code may not be used for any purpose without the express written
// consent of the author.  See the LICENSE.txt file for details.
//
//
// DESCRIPTION
//
// This header file contains project-wide type definitions and macros.
//
///////////////////////////////////////////////////////////////////////////////


#ifndef __COMMON_H__
#define __COMMON_H__

#include "config.h"
#include <limits.h>

typedef unsigned int       UINT;
typedef signed   int       INT;
typedef unsigned long long UINT64;
typedef signed   long long INT64;
typedef unsigned int       UINT32;
typedef signed   int       INT32;
typedef unsigned short     UINT16;
typedef signed   short     INT16;
typedef unsigned char      UINT8;
typedef signed   char      INT8;

#if CFG_SIMSYS64
typedef UINT64             ADDRINT;
#else
typedef UINT32             ADDRINT;
#endif

#define UINT64_MAX ULONGLONG_MAX
#define UINT32_MAX UINT_MAX
#define UINT16_MAX 65535
#define UINT8_MAX  255
#define INT64_MAX  LONGLONG_MAX
#define INT32_MAX  INT_MAX
#define INT32_MIN  INT_MIN
#define INT16_MAX  (32767)
#define INT16_MIN  (-32768)
#define INT8_MAX   127
#define INT8_MIN   (-128)

#if CFG_64BIT_REGVALS || CFG_GUEST64
typedef UINT64 IVAL;
typedef INT64  SVAL;
#define IC(x)  x##ULL
#define SIC(x) x##LL
#else
typedef UINT32 IVAL;
typedef INT32  SVAL;
#define IC(x) x##UL
#define SIC(x) x##L
#endif

#if CFG_GUEST64
typedef UINT64 GuestAddr;
#define GUESTADDR_MAX UINT64_MAX
#else
typedef UINT32 GuestAddr;
#define GUESTADDR_MAX UINT32_MAX
#endif

#if CFG_SIMSYS_ALIGNMENT
#define UNALIGNED __unaligned
#else
#define UNALIGNED
#endif

#if defined(NULL)
#undef NULL
#endif
#define NULL 0
#if !defined(TRUE)
#define TRUE 1
#endif
#if !defined(FALSE)
#define FALSE 0
#endif

#include "softfloat.h"

// FP stuff for FP abstraction
#define FP80 floatx80
#define FP64 float64
#define FP32 float32

typedef union {
  float64 bits;
  double value;
} FP64U;

#define FP_BITS32(x) ((unsigned int)x)
#define FP_BITS64(x) ((unsigned long long)x)

#define FP_CVT_80_32(x) floatx80_to_float32(x)
#define FP_CVT_80_64(x) floatx80_to_float64(x)
#define FP_CVT_80_I2(x) floatx80_to_int16(x)
#define FP_CVT_80_I4(x) floatx80_to_int32(x)
#define FP_CVT_80_I8(x) floatx80_to_int64(x)
#define FP_CVT_32_80(x) float32_to_floatx80(x)
#define FP_CVT_64_80(x) float64_to_floatx80(x)
#define FP_CVT_I2_80(x) int32_to_floatx80((INT32)(INT16)x)
#define FP_CVT_I4_80(x) int32_to_floatx80((INT32)x)
#define FP_CVT_I8_80(x) int64_to_floatx80((INT64)x)

#define FP_RND_INT(x)  floatx80_round_to_int(x)
#define FP_ADD floatx80_add
#define FP_SUB floatx80_sub
#define FP_MUL floatx80_mul
#define FP_DIV floatx80_div
#define FP_REM floatx80_rem
#define FP_SQRT floatx80_sqrt
#define FP_SUBR floatx80_subr
#define FP_DIVR floatx80_divr


#ifdef LESS86
extern int log2(int x);
#endif

#endif
